<template>
    <div id="map"></div>
    <div class="controls">
        <!-- <button id="start" @click="startMoving">开始移动</button>
        <button id="stop" @click="stopMoving">停止移动</button> -->
        <!-- <div>
            速度(km/h):
            <input type="range" id="speed" min="1" max="120" value="0.5" @input="onInput" />
        </div>
        <div>
            平滑系数:
            <input type="range" id="smoothness" min="1" max="100" value="20" @input="smoothness" />
        </div> -->
    </div>
    <div class="option-btn__list">
        <button class="btn-item" @click="startMoving">开始</button>
        <button class="btn-item" @click="stopMoving">暂停</button>
    </div>
</template>
<script lang="ts" setup>
import TileLayer from 'ol/layer/Tile';
import { XYZ } from 'ol/source';
import { TDMAP_TK } from '@/utils/constant';
import MapType from 'ol/Map.js';
import { Feature, View } from 'ol';
import { fromLonLat, toLonLat } from 'ol/proj';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import { LineString, Point } from 'ol/geom';
import Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke';
import Icon from 'ol/style/Icon';
import { Coordinate } from 'ol/coordinate';
import { getDistance } from 'ol/sphere';
// 天地图矢量图层
const tdMapVectorLayer = new TileLayer({
    zIndex: 30,
    className: 'tdVector',
    visible: true,
    source: new XYZ({
        url: `https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${TDMAP_TK}`,
        wrapX: false
    })
});
// 天地图标注层
const tdMapCvaLayer = new TileLayer({
    zIndex: 31,
    className: 'tdCva',
    visible: true,
    source: new XYZ({
        url: `https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=${TDMAP_TK}`,
        wrapX: false
    })
});
let map: MapType;
let carFeature: any;
// 2. 创建测试路线
const routeCoords: Coordinate[] = [
    [116.478935, 39.997761],
    [116.478939, 39.997825],
    [116.478912, 39.998549],
    [116.478912, 39.998549],
    [116.478998, 39.998555],
    [116.478998, 39.998555],
    [116.479282, 39.99856],
    [116.479658, 39.998528],
    [116.480151, 39.998453],
    [116.480784, 39.998302],
    [116.480784, 39.998302],
    [116.481149, 39.998184],
    [116.481573, 39.997997],
    [116.481863, 39.997846],
    [116.482072, 39.997718],
    [116.482362, 39.997718],
    [116.483633, 39.998935],
    [116.48367, 39.998968],
    [116.484648, 39.999861]
].map(coord => fromLonLat(coord));

// 5. 使用车头向上的PNG图片（示例URL，请替换为实际URL）
const carIconUrl = new URL('@/assets/img/car.png', import.meta.url).href;

// 预计算路径信息（每段50个点）
const pathData = precomputePath(routeCoords, 50);
const pathPoints = pathData.points;
const totalPathDistance = pathData.totalDistance;

// 7. 小车移动控制
let animationId = 0;
let currentDistance = 0;
// let speed = 30; // km/h
let speed = 0.3;
let lastTimestamp = 0;
let smoothFactor = 0.3;
let lastAngle = pathPoints[0].angle;

// 带平滑的角度更新
function updateSmoothedAngle(newAngle: number) {
    newAngle = -newAngle + Math.PI / 2;
    // 角度平滑处理（避免360度跳变）
    const angleDiff = ((newAngle - lastAngle + Math.PI) % (2 * Math.PI)) - Math.PI;
    const smoothedAngle = lastAngle + angleDiff * smoothFactor;

    lastAngle = smoothedAngle;
    return smoothedAngle;
}
// 更新小车样式
function updateCarStyle(position: Coordinate, angle: number) {
    carFeature.setStyle(
        new Style({
            image: new Icon({
                src: carIconUrl,
                scale: 1,
                rotation: angle,
                anchor: [0.5, 0.5],
                rotateWithView: true
            })
        })
    );
    carFeature.getGeometry().setCoordinates(position);
}

// 根据距离查找路径点
function findPathPointByDistance(distance: number) {
    distance = Math.max(0, Math.min(distance, totalPathDistance));

    // 二分查找优化
    let low = 0;
    let high = pathPoints.length - 1;
    let bestIndex = 0;

    while (low <= high) {
        const mid = Math.floor((low + high) / 2);
        if (pathPoints[mid].distance < distance) {
            bestIndex = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    // 线性插值
    if (bestIndex < pathPoints.length - 1) {
        const p1 = pathPoints[bestIndex];
        const p2 = pathPoints[bestIndex + 1];
        const ratio = (distance - p1.distance) / (p2.distance - p1.distance);

        const interpolatedPoint = [
            p1.point[0] + (p2.point[0] - p1.point[0]) * ratio,
            p1.point[1] + (p2.point[1] - p1.point[1]) * ratio
        ];

        const interpolatedAngle = p1.angle + (p2.angle - p1.angle) * ratio;

        return {
            point: interpolatedPoint,
            angle: interpolatedAngle
        };
    }

    return {
        point: pathPoints[bestIndex].point,
        angle: pathPoints[bestIndex].angle
    };
}

function moveAlong(timestamp: number) {
    if (!lastTimestamp) lastTimestamp = timestamp;
    const elapsed = timestamp - lastTimestamp;
    lastTimestamp = timestamp;

    // 计算移动距离 (km/h → m/ms)
    const distanceToMove = ((speed * 1000) / 3600) * elapsed;

    // 更新当前位置
    currentDistance = Math.min(currentDistance + distanceToMove, totalPathDistance);

    // 查找当前点信息
    const currentPointInfo = findPathPointByDistance(currentDistance);

    // 平滑角度
    const smoothedAngle = updateSmoothedAngle(currentPointInfo.angle);

    // 更新小车
    updateCarStyle(currentPointInfo.point, smoothedAngle);

    // 保持地图中心跟随小车
    map.getView().setCenter(currentPointInfo.point);

    // 检查是否到达终点
    if (currentDistance >= totalPathDistance) {
        stopMoving();
        return;
    }

    animationId = requestAnimationFrame(moveAlong);
}

function startMoving() {
    if (!animationId) {
        if (currentDistance >= totalPathDistance) {
            currentDistance = 0;
            lastAngle = pathPoints[0].angle;
        }
        lastTimestamp = 0;
        animationId = requestAnimationFrame(moveAlong);
    }
}

function stopMoving() {
    if (animationId) {
        cancelAnimationFrame(animationId);
        animationId = 0;
    }
}

// 6. 预计算路径信息（位置+方向）
function precomputePath(coords: Coordinate[], segmentsPerSection: number) {
    const pathInfo = [];
    let totalDistance = 0;

    // 生成密集路径点并计算方向
    for (let i = 0; i < coords.length - 1; i++) {
        const start = coords[i];
        const end = coords[i + 1];

        for (let j = 0; j <= segmentsPerSection; j++) {
            const ratio = j / segmentsPerSection;
            const point = [
                start[0] + (end[0] - start[0]) * ratio,
                start[1] + (end[1] - start[1]) * ratio
            ];

            // 计算方向（正东为0，调整为车头向上）
            let angle = 0;
            if (j < segmentsPerSection) {
                const nextPoint = [
                    start[0] + (end[0] - start[0]) * ((j + 1) / segmentsPerSection),
                    start[1] + (end[1] - start[1]) * ((j + 1) / segmentsPerSection)
                ];
                const dx = nextPoint[0] - point[0];
                const dy = nextPoint[1] - point[1];
                // angle = Math.atan2(dy, dx) - Math.PI / 2;
                angle = Math.atan2(dy, dx);
            } else if (i < coords.length - 2) {
                // 处理段末点的方向（使用下一段的起点）
                const nextStart = coords[i + 1];
                const nextEnd = coords[i + 2];
                const nextPoint = [
                    nextStart[0] + (nextEnd[0] - nextStart[0]) * (1 / segmentsPerSection),
                    nextStart[1] + (nextEnd[1] - nextStart[1]) * (1 / segmentsPerSection)
                ];
                const dx = nextPoint[0] - point[0];
                const dy = nextPoint[1] - point[1];
                angle = Math.atan2(dy, dx) - Math.PI / 2;
            }

            // 计算段内距离
            let segmentDistance = 0;
            if (j > 0) {
                const prevPoint = pathInfo[pathInfo.length - 1].point;
                const from = toLonLat(prevPoint);
                const to = toLonLat(point);
                segmentDistance = getDistance(from, to);
                totalDistance += segmentDistance;
            }

            pathInfo.push({
                point: point,
                angle: angle,
                distance: totalDistance,
                segmentDistance: segmentDistance
            });
        }
    }

    return {
        points: pathInfo,
        totalDistance: totalDistance
    };
}

function resetCar() {
    currentDistance = 0;
    lastAngle = pathPoints[0].angle;
    updateCarStyle(pathPoints[0].point, 0);
}

// const smoothness = (e: any) => {
//     smoothFactor = 0.05 + (parseInt(e.target.value) / 100) * 0.45;
// };

const initMap = () => {
    // 1. 初始化地图
    map = new MapType({
        target: 'map',
        layers: [tdMapVectorLayer, tdMapCvaLayer],
        view: new View({
            center: fromLonLat([116.478935, 39.997761]),
            zoom: 18
        })
    });
    // 3. 创建路线图层
    const lineFeature = new Feature({
        geometry: new LineString(routeCoords)
    });
    const routeLayer = new VectorLayer({
        source: new VectorSource({
            features: [lineFeature]
        }),
        style: new Style({
            stroke: new Stroke({
                color: '#4285F4',
                width: 6
            })
        }),
        zIndex: 33
    });
    map.addLayer(routeLayer);
    const arrowsSource = new VectorSource();
    // 计算箭头位置和角度（每隔一段距离放一个箭头）
    const line = lineFeature.getGeometry()!;
    const length = line.getLength();
    const step = length / 10; // 每10%路径长度放一个箭头

    for (let i = 0; i < length; i += step) {
        const segment = line.getCoordinateAt(i / length);
        const segmentNext = line.getCoordinateAt(Math.min((i + 1) / length, 1));

        // 计算角度（弧度）
        const dx = segmentNext[0] - segment[0];
        const dy = segmentNext[1] - segment[1];
        const angle = Math.atan2(dy, dx);

        const arrow = new Feature({
            geometry: new Point(segment)
        });
        arrow.setStyle(
            new Style({
                image: new Icon({
                    src:
                        'data:image/svg+xml;utf8,' +
                        '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">' +
                        '<path fill="white" d="M12 2L2 12l10 10 10-10z"/>' + // 更瘦长的三角形
                        '</svg>',
                    scale: 1,
                    rotation: angle, // 箭头方向跟随路径
                    rotateWithView: true, // 保持箭头方向与地图旋转同步,

                    anchor: [0.5, 0.5] // 中心锚点
                })
            })
        );
        arrowsSource.addFeature(arrow);
    }
    // 5. 添加方向箭头（三角形图标）
    const arrowsLayer = new VectorLayer({
        source: arrowsSource,
        zIndex: 33,
        visible: true,
        className: 'arrows'
    });
    map.addLayer(arrowsLayer);
    // 4. 创建小车（使用车头向上的PNG图片）
    carFeature = new Feature({
        geometry: new Point(routeCoords[0])
    });
    carFeature.setStyle(
        new Style({
            image: new Icon({
                src: carIconUrl,
                scale: 1,
                rotation: 0,
                anchor: [0.5, 0.5],
                rotateWithView: true
            })
        })
    );
    const carLayer = new VectorLayer({
        source: new VectorSource({
            features: [carFeature]
        }),
        zIndex: 33
    });
    map.addLayer(carLayer);
    // 9. 初始设置
    resetCar();
};
// const onInput = (e: any) => {
//     speed = parseInt(e.target.value);
// };
onMounted(() => {
    initMap();
});
</script>
<style lang="scss" scoped>
#map {
    width: 100%;
    height: 100vh;
}
.controls {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 1000;
    background: rgba(255, 255, 255, 0.8);
    padding: 10px;
    border-radius: 5px;
}
.option-btn__list {
    position: fixed;
    right: 20px;
    top: 20px;
    display: flex;
    z-index: 99;
    gap: 10px;
    .btn-item {
        border: none;
        background-color: #1e71ff;
        border-radius: 20px;
        padding: 0 20px;
        text-align: center;
        color: #fff;
        height: 36px;
        line-height: 36px;
        cursor: pointer;
    }
}
</style>
